Omandage functools.lru_cache, functools.singledispatch ja functools.wraps selle pÔhjaliku juhendiga rahvusvahelistele Pythoni arendajatele, suurendades koodi tÔhusust ja paindlikkust.
Pythoni Potentsiaali Vallandamine: TĂ€iustatud `functools` Decorators Globaalsetele Arendajatele
Tarkvaraarenduse pidevalt arenevas maastikus on Python jĂ€tkuvalt domineeriv jĂ”ud, mida tĂ€histatakse selle loetavuse ja ulatuslike teekide eest. Arendajatele ĂŒle kogu maailma on selle tĂ€iustatud funktsioonide omandamine tĂ”husate, vastupidavate ja hooldatavate rakenduste loomiseks ĂŒlioluline. Pythoni kĂ”ige vĂ”imsamate tööriistade hulgas on `functools` moodulis leiduvad decoratorid. See juhend kĂ€sitleb kolme olulist decoratorit: `lru_cache` jĂ”udluse optimeerimiseks, `singledispatch` paindlikuks funktsioonide ĂŒlekoormamiseks ja `wraps` funktsioonide metadata sĂ€ilitamiseks. Neid decoratoreid mĂ”istes ja rakendades saavad rahvusvahelised Pythoni arendajad oluliselt parandada oma kodeerimistavasid ja tarkvara kvaliteeti.
Miks `functools` Decorators on Globaalsele Vaatajaskonnale Olulised
`functools` moodul on loodud kĂ”rgema jĂ€rgu funktsioonide ja helistatavate objektide arenduse toetamiseks. Decorators, mis on Python 3.0-s tutvustatud sĂŒntaktiline suhkur, vĂ”imaldavad meil funktsioone ja meetodeid puhtal ja loetaval viisil muuta vĂ”i tĂ€iustada. Globaalse vaatajaskonna jaoks tĂ€hendab see mitmeid peamisi eeliseid:
- Universaalsus: Pythoni sĂŒntaks ja pĂ”hiteegid on standardiseeritud, muutes sellised kontseptsioonid nagu decoratorid universaalselt mĂ”istetavaks, sĂ”ltumata geograafilisest asukohast vĂ”i programmeerimistaustast.
- TÔhusus: `lru_cache` vÔib drastiliselt parandada arvutuslikult kallite funktsioonide jÔudlust, mis on kriitiline tegur erinevates piirkondades esineda vÔivate vÔrgu latentsuse vÔi ressursipiirangute korral.
- Paindlikkus: `singledispatch` vĂ”imaldab koodi, mis suudab kohaneda erinevate andmetĂŒĂŒpidega, edendades ĂŒldisemat ja kohandatavamat koodibaasi, mis on oluline rakenduste jaoks, mis teenindavad erinevaid kasutajabaase erinevate andmevormingutega.
- Hooldatavus: `wraps` tagab, et decoratorid ei varjutaks algse funktsiooni identiteeti, aidates silumisraskusi ja introspektsiooni, mis on rahvusvaheliste koostöömeeskondade jaoks ĂŒlioluline.
Uurime igaĂŒhte neist decoratoritest ĂŒksikasjalikult.
1. `functools.lru_cache`: Memoization jÔudluse optimeerimiseks
Ăks levinumaid programmeerimise jĂ”udluse kitsaskohti tuleneb korduvatest arvutustest. Kui funktsiooni kutsutakse sama argumendiga mitu korda ja selle tĂ€itmine on kallis, on tulemuse iga kord uuesti arvutamine raiskamine. Siin muutub hindamatuks memoization, meetod kallite funktsioonikĂ”nede tulemuste vahemĂ€llu salvestamiseks ja vahemĂ€llu salvestatud tulemuse tagastamiseks, kui samad sisendid ilmuvad uuesti. Pythoni `functools.lru_cache` decorator pakub selleks elegantset lahendust.
Mis on `lru_cache`?
`lru_cache` tĂ€hendab 'Least Recently Used cache' (hiljuti kĂ”ige vĂ€hem kasutatud vahemĂ€lu). See on decorator, mis ĂŒmbritseb funktsiooni, salvestades selle tulemused sĂ”nastikku. Kui dekoreeritud funktsiooni kutsutakse, kontrollib `lru_cache` esmalt, kas antud argumentide tulemus on juba vahemĂ€lus. Kui jah, tagastatakse vahemĂ€llu salvestatud tulemus kohe. Kui ei, tĂ€idetakse funktsioon, selle tulemus salvestatakse vahemĂ€llu ja seejĂ€rel tagastatakse. "Hiljuti kĂ”ige vĂ€hem kasutatud" tĂ€hendab, et kui vahemĂ€lu jĂ”uab oma maksimaalse suuruseni, visatakse uute kirjete jaoks ruumi tegemiseks hiljuti kĂ”ige vĂ€hem kasutatud ĂŒksus vĂ€lja.
PÔhikasutus ja Parameetrid
`lru_cache` kasutamiseks importige see lihtsalt ja rakendage seda oma funktsioonile decoratorina:
from functools import lru_cache
@lru_cache(maxsize=128)
def expensive_computation(x, y):
"""Simuleerib kallist arvutust."""
print(f"Teostatakse kallis arvutus {x}, {y} jaoks...")
# Simuleerige mĂ”nda rasket tööd, nt. vĂ”rguĂŒhendus, keerukas matemaatika
return x * y + x / 2
Parameeter `maxsize` kontrollib salvestatavate tulemuste maksimaalset arvu. Kui `maxsize` on seatud `None`-ks, vÔib vahemÀlu kasvada lÔputult. Kui see on seatud positiivseks tÀisarvuks, mÀÀrab see vahemÀlu suuruse. Kui vahemÀlu on tÀis, viskab see vÀlja hiljuti kÔige vÀhem kasutatud kirjed. `maxsize` vaikimisi vÀÀrtus on 128.
PÔhilised Kaalutlused ja TÀiustatud Kasutus
- Hashable Argumendid: VahemĂ€luga funktsioonile edastatavad argumendid peavad olema hashable. See tĂ€hendab, et muutumatud tĂŒĂŒbid nagu numbrid, stringid, tuplid (mis sisaldavad ainult hashable ĂŒksusi) ja frozensets on vastuvĂ”etavad. Muutuvad tĂŒĂŒbid nagu listid, sĂ”nastikud ja sets ei ole.
- `typed=True` Parameeter: Vaikimisi kĂ€sitleb `lru_cache` erinevatest tĂŒĂŒpidest pĂ€rit argumente, mis vĂ”rduvad vĂ”rdselt, kui ĂŒhesugused. NĂ€iteks `cached_func(3)` ja `cached_func(3.0)` vĂ”ivad tabada sama vahemĂ€lu kirjet. `typed=True` seadmine muudab vahemĂ€lu argumentide tĂŒĂŒpide suhtes tundlikuks. Seega `cached_func(3)` ja `cached_func(3.0)` salvestatakse vahemĂ€llu eraldi. See vĂ”ib olla kasulik, kui funktsiooni sees on tĂŒĂŒbispetsiifiline loogika.
- VahemĂ€lu TĂŒhjendamine: `lru_cache` pakub meetodeid vahemĂ€lu haldamiseks. `cache_info()` tagastab nimetatud tupli statistiliste andmetega vahemĂ€lu tabamuste, möödalaskmiste, praeguse suuruse ja maksimaalse suuruse kohta. `cache_clear()` tĂŒhjendab kogu vahemĂ€lu.
@lru_cache(maxsize=32)
def fibonacci(n):
if n < 2:
return n
return fibonacci(n-1) + fibonacci(n-2)
print(fibonacci(10))
print(fibonacci.cache_info())
fibonacci.cache_clear()
print(fibonacci.cache_info())
`lru_cache` Globaalne Rakendamine
Kujutage ette stsenaariumit, kus rakendus pakub reaalajas valuutavahetuskursse. Nende kurside hankimine vÀlisest API-st vÔib olla aeglane ja kulutada ressursse. `lru_cache` saab rakendada funktsioonile, mis neid kursse hangib:
import requests
from functools import lru_cache
@lru_cache(maxsize=10)
def get_exchange_rate(base_currency, target_currency):
"""Hangib uusima vahetuskursi vÀlisest API-st."""
# PÀrisrakenduses kÀsitsege API vÔtmeid, veatöötlust jne.
api_url = f"https://api.example.com/rates?base={base_currency}&target={target_currency}"
try:
response = requests.get(api_url, timeout=5) # MÀÀrake aegumistÀhtaeg
response.raise_for_status() # TÔstke HTTPError vigaste vastuste (4xx vÔi 5xx) korral
data = response.json()
return data['rate']
except requests.exceptions.RequestException as e:
print(f"Viga vahetuskursi hankimisel: {e}")
return None
# Kasutaja Euroopas kĂŒsib EUR-USD kurssi
europe_user_rate = get_exchange_rate('EUR', 'USD')
print(f"EUR kuni USD: {europe_user_rate}")
# Kasutaja Aasias kĂŒsib EUR-USD kurssi
asian_user_rate = get_exchange_rate('EUR', 'USD') # See tabab vahemÀlu, kui see on maxsize'is
print(f"EUR kuni USD (vahemÀlus): {asian_user_rate}")
# Kasutaja Ameerikas kĂŒsib USD-EUR kurssi
americas_user_rate = get_exchange_rate('USD', 'EUR')
print(f"USD kuni EUR: {americas_user_rate}")
Selles nĂ€ites, kui mitu kasutajat kĂŒsib sama valuutapaari lĂŒhikese aja jooksul, tehakse kallis API-kĂ”ne ainult ĂŒks kord. See on eriti kasulik teenuste jaoks, millel on globaalne kasutajaskond, kes pÀÀseb juurde sarnastele andmetele, vĂ€hendades serveri koormust ja parandades vastusaegu kĂ”igile kasutajatele.
2. `functools.singledispatch`: Generilised Funktsioonid ja PolĂŒmorfism
Paljudes programmeerimisparadigmas vĂ”imaldab polĂŒmorfism erinevat tĂŒĂŒpi objektide kĂ€sitlemist ĂŒhise ĂŒlemklassi objektidena. Pythonis saavutatakse see sageli parditĂŒĂŒpimise kaudu. Siiski olukordades, kus peate defineerima kĂ€itumise, mis pĂ”hineb argumendi konkreetsel tĂŒĂŒbil, pakub `singledispatch` vĂ”imsat mehhanismi generiliste funktsioonide loomiseks tĂŒĂŒbipĂ”hise vĂ€ljakutsumisega. See vĂ”imaldab teil defineerida funktsioonile vaikimisi tĂ€itmisviisi ja seejĂ€rel registreerida spetsiaalseid tĂ€itmisviise erinevatele argumenditĂŒĂŒpidele.
Mis on `singledispatch`?
`singledispatch` on funktsioonide decorator, mis vĂ”imaldab generilisi funktsioone. Generiline funktsioon on funktsioon, mis kĂ€itub erinevalt sĂ”ltuvalt selle esimese argumendi tĂŒĂŒbist. Te defineerite baasfunktsiooni, mida dekoreeritakse `@singledispatch`-ga, ja seejĂ€rel kasutate `@base_function.register(Type)` decoratorit spetsiaalsete tĂ€itmisviiside registreerimiseks erinevate tĂŒĂŒpide jaoks.
PÔhikasutus
Illustreerime seda andmete vormindamise nÀitega erinevate vÀljundvormingute jaoks:
from functools import singledispatch
@singledispatch
def format_data(data):
"""Vaikimisi tÀitmisviis: vormindab andmed stringina."""
return str(data)
@format_data.register(int)
def _(data):
"""Vormindab tÀisarve komadega tuhandete eraldamiseks."""
return "{:, .0f}".format(data)
@format_data.register(float)
def _(data):
"""Vormindab ujukomaarve kahe komakohaga."""
return "{:.2f}".format(data)
@format_data.register(list)
def _(data):
"""Vormindab listid, ĂŒhendades elemendid pĂŒstkriipsu '|' abil."""
return " | ".join(map(str, data))
Pange tĂ€hele `_` kasutamist funktsiooni nimena registreeritud tĂ€itmisviiside jaoks. See on tavaline konventsioon, kuna registreeritud funktsiooni nimi ei oma tĂ€htsust; ainult selle tĂŒĂŒp on vĂ€ljakutsumise jaoks oluline. VĂ€ljakutsumine toimub generilisele funktsioonile edastatava esimese argumendi tĂŒĂŒbi pĂ”hjal.
Kuidas VÀljakutsumine Töötab
Kui kutsutakse `format_data(some_value)`:
- Python kontrollib `some_value` tĂŒĂŒpi.
- Kui sellele konkreetsele tĂŒĂŒbile (nt. `int`, `float`, `list`) on registreering olemas, kutsutakse vastavat registreeritud funktsiooni.
- Kui spetsiaalset registreeringut ei leita, kutsutakse algne funktsioon, mida dekoreeritakse `@singledispatch`-ga (vaikimisi tÀitmisviis).
- `singledispatch` kĂ€sitleb ka pĂ€rimist. Kui tĂŒĂŒp `Subclass` pĂ€rib `BaseClass`-ilt ja `format_data`-l on registreering `BaseClass`-i jaoks, kasutatakse `SubClass`-i eksemplariga `format_data`-i kutsumisel `BaseClass`-i tĂ€itmisviisi, kui `SubClass`-i spetsiaalset registreeringut pole.
`singledispatch` Globaalne Rakendamine
Kujutage ette rahvusvahelist andmetöötlusteenust. Kasutajad vĂ”ivad esitada andmeid erinevates vormingutes (nt. arvulised vÀÀrtused, geograafilised koordinaadid, ajatemplid, ĂŒksuste loendid). Funktsioon, mis neid andmeid töötleb ja standardiseerib, vĂ”ib `singledispatch`-ist suuresti kasu saada.
from functools import singledispatch
from datetime import datetime
@singledispatch
def process_input(value):
"""Vaikimisi töötlus: logib tundmatud tĂŒĂŒbid."""
print(f"Logib tundmatut sisendtĂŒĂŒpi: {type(value).__name__} - {value}")
return None
@process_input.register(str)
def _(value):
"""Töötleb stringid, eeldades, et need vÔivad olla kuupÀevad vÔi lihtne tekst."""
try:
# Proovige parsilge ISO vormingus kuupÀevana
return datetime.fromisoformat(value.replace('Z', '+00:00'))
except ValueError:
# Kui pole kuupÀev, tagastage nagu on (vÔi tehke muu tekstiline töötlus)
return value.strip()
@process_input.register(int)
def _(value):
"""Töötleb tÀisarve, eeldades, et need on kehtivad tootearved."""
if value < 100000: # NĂ€ite jaoks suvaline valideerimine
print(f"Hoiatus: Potentsiaalselt kehtetu tootearve: {value}")
return f"PID-{value:06d}" # Vormindab kui PID-000001
@process_input.register(tuple)
def _(value):
"""Töötleb tuplid, eeldades, et need on geograafilised koordinaadid (lat, lon)."""
if len(value) == 2 and all(isinstance(coord, (int, float)) for coord in value):
return {'latitude': value[0], 'longitude': value[1]}
else:
print(f"Hoiatus: Kehtetu koordinaatide tupli vorming: {value}")
return None
# --- NĂ€itusekasutus rahvusvahelisele vaatajaskonnale ---
# Jaapani kasutaja esitab ajatemplit stringina
input1 = "2023-10-27T10:00:00Z"
processed1 = process_input(input1)
print(f"Sisend: {input1}, Töödeldud: {processed1}")
# USA kasutaja esitab tootearve
input2 = 12345
processed2 = process_input(input2)
print(f"Sisend: {input2}, Töödeldud: {processed2}")
# Brasiilia kasutaja esitab geograafilised koordinaadid
input3 = ( -23.5505, -46.6333 )
processed3 = process_input(input3)
print(f"Sisend: {input3}, Töödeldud: {processed3}")
# Austraalia kasutaja esitab lihtsa tekststringi
input4 = "Sydney Office"
processed4 = process_input(input4)
print(f"Sisend: {input4}, Töödeldud: {processed4}")
# MĂ”ni muu tĂŒĂŒp
input5 = [1, 2, 3]
processed5 = process_input(input5)
print(f"Sisend: {input5}, Töödeldud: {processed5}")
`singledispatch` vĂ”imaldab arendajatel luua programmeerimisteeke vĂ”i funktsioone, mis suudavad graatsiliselt kĂ€sitleda mitmesuguseid sisendtĂŒĂŒpe ilma, et funktsiooni sees oleks vaja kasutada otseseid tĂŒĂŒbikontrolle (`if isinstance(...)`). See loob puhtama ja laiendatavama koodi, mis on vĂ€ga kasulik rahvusvahelistes projektides, kus andmevormingud vĂ”ivad oluliselt erineda.
3. `functools.wraps`: Funktsiooni Metaandmete SĂ€ilitamine
Decorators on vĂ”imas tööriist olemasolevate funktsioonide tĂ€iustamiseks, ilma nende algset koodi muutmata. Siiski on decoratori rakendamise kĂ”rvalmĂ”juks see, et algse funktsiooni metaandmed (nagu selle nimi, docstring ja annotatsioonid) asendatakse decoratori ĂŒmbris funktsiooni metaandmetega. See vĂ”ib pĂ”hjustada probleeme introspektsioonitööriistadele, siluritele ja dokumentatsioonigeneraatoritele. `functools.wraps` on decorator, mis lahendab selle probleemi.
Mis on `wraps`?
`wraps` on decorator, mida te rakendate oma kohandatud decoratori sees olevasse ĂŒmbris funktsiooni. See kopeerib algse funktsiooni metaandmed ĂŒmbris funktsioonile. See tĂ€hendab, et pĂ€rast teie decoratori rakendamist ilmub dekoreeritud funktsioon vĂ€lismaailmale justkui oleks see algne funktsioon, sĂ€ilitades selle nime, docstringi ja muud atribuudid.
PÔhikasutus
Loome lihtsa logimiste decoratori ja nÀeme efekti koos `wraps`-ga ja ilma.
Ilma `wraps`-ta
def simple_logging_decorator(func):
def wrapper(*args, **kwargs):
print(f"Kutsutakse funktsiooni: {func.__name__}")
result = func(*args, **kwargs)
print(f"LÔpetati funktsiooni: {func.__name__}")
return result
return wrapper
@simple_logging_decorator
def greet(name):
"""Tervitab inimest."""
return f"Hello, {name}!"
print(f"Funktsiooni nimi: {greet.__name__}")
print(f"Funktsiooni docstring: {greet.__doc__}")
print(greet("World"))
Kui seda kÀivitate, mÀrkate, et `greet.__name__` on 'wrapper' ja `greet.__doc__` on `None`, kuna `wrapper` funktsiooni metaandmed on asendanud `greet`-i omad.
Koos `wraps`-ga
Rakendame nĂŒĂŒd `wraps`-i `wrapper` funktsioonile:
from functools import wraps
def robust_logging_decorator(func):
@wraps(func) # Rakendage wraps ĂŒmbris funktsioonile
def wrapper(*args, **kwargs):
print(f"Kutsutakse funktsiooni: {func.__name__}")
result = func(*args, **kwargs)
print(f"LÔpetati funktsiooni: {func.__name__}")
return result
return wrapper
@robust_logging_decorator
def greet_properly(name):
"""Tervitab inimest (korrektelt dekoreeritud)."""
return f"Hello, {name}!"
print(f"Funktsiooni nimi: {greet_properly.__name__}")
print(f"Funktsiooni docstring: {greet_properly.__doc__}")
print(greet_properly("World Again"))
Selle teise nÀite kÀivitamine nÀitab:
Funktsiooni nimi: greet_properly
Funktsiooni docstring: Tervitab inimest (korrektelt dekoreeritud).
Kutsutakse funktsiooni: greet_properly
LÔpetati funktsiooni: greet_properly
Hello, World Again!
Nimi `__name__` on Ôigesti seatud 'greet_properly' ja `__doc__` string on sÀilinud. `wraps` kopeerib ka teisi asjakohaseid atribuute nagu `__module__`, `__qualname__` ja `__annotations__`.
`wraps` Globaalne Rakendamine
Koostöökeskkondades rahvusvahelises arenduses on selge ja ligipÀÀsetav kood esmatÀhtis. Silumisraskused vÔivad olla keerukamad, kui meeskonnaliikmed on erinevates ajavööndites vÔi neil on erinev tuttavus koodibaasiga. Funktsiooni metaandmete sÀilitamine `wraps`-iga aitab sÀilitada koodi selgust ning lihtsustab silumis- ja dokumenteerimistööd.
NÀiteks kaaluge decoratorit, mis lisab autentimiskontrolle enne veeb API lÔpp-punkti kÀsitseja tÀitmist. Ilma `wraps`-ta vÔivad lÔpp-punkti nimi ja docstring kaduda, muutes teiste arendajate (vÔi automatiseeritud tööriistade) jaoks raskemaks mÔista, mida lÔpp-punkt teeb vÔi milliseid probleeme parandada. `wraps`-i kasutamine tagab, et lÔpp-punkti identiteet jÀÀb selgeks.
from functools import wraps
def require_admin_role(func):
@wraps(func)
def wrapper(*args, **kwargs):
# PĂ€ris rakenduses kontrolliks see kasutaja rolle sessioonist/tokenist
is_admin = kwargs.get('user_role') == 'admin'
if not is_admin:
raise PermissionError("Admin roll on vajalik")
return func(*args, **kwargs)
return wrapper
@require_admin_role
def delete_user(user_id, user_role=None):
"""Kustutab kasutaja sĂŒsteemist. NĂ”uab administraatori Ă”igusi."""
print(f"Kustutatakse kasutaja {user_id}...")
# Tegelik kustutamise loogika siin
return True
# --- NĂ€itusekasutus ---
# Simuleerides administraatori kasutaja pÀringut
try:
delete_user(101, user_role='admin')
except PermissionError as e:
print(e)
# Simuleerides tavakasutaja pÀringut
try:
delete_user(102, user_role='user')
except PermissionError as e:
print(e)
# Dekoreeritud funktsiooni kontrollimine
print(f"Funktsiooni nimi: {delete_user.__name__}")
print(f"Funktsiooni docstring: {delete_user.__doc__}")
# MÀrkus: __annotations__ sÀilitataks ka, kui see oleks olemas algsel funktsioonil.
`wraps` on asendamatu tööriist kĂ”igile, kes loovad korduvkasutatavaid decoratoreid vĂ”i kujundavad programmeerimisteeke, mis on mĂ”eldud laiemaks kasutamiseks. See tagab, et tĂ€iustatud funktsioonid kĂ€ituvad oma metaandmete osas nii ettearvatavalt kui vĂ”imalik, mis on rahvusvahelise tarkvaraprojektide hooldatavuse ja koostöö jaoks ĂŒlioluline.
Decoratorite Kombineerimine: VĂ”imas SĂŒnergia
`functools` decoratorite tegelik vĂ”imsus ilmneb sageli siis, kui neid kasutatakse koos. Vaatame stsenaariumi, kus soovime funktsiooni optimeerida `lru_cache`-ga, muuta selle polĂŒmorfseks `singledispatch`-iga ja tagada metaandmete sĂ€ilitamine `wraps`-iga.
Kuigi `singledispatch` nĂ”uab, et dekoreeritud funktsioon oleks vĂ€ljakutsumise alus ja `lru_cache` optimeerib mis tahes funktsiooni tĂ€itmist, saavad nad koos töötada. `wraps` rakendatakse aga tavaliselt kohandatud decoratoris metaandmete sĂ€ilitamiseks. `lru_cache` ja `singledispatch` rakendatakse ĂŒldiselt otse funktsioonidele vĂ”i `singledispatch`-i puhul baasfunktsioonile.
Tavalisem kombinatsioon on kasutada kohandatud decoratoris `lru_cache` ja `wraps`:
from functools import lru_cache, wraps
def cached_and_logged(maxsize=128):
def decorator(func):
@wraps(func)
@lru_cache(maxsize=maxsize)
def wrapper(*args, **kwargs):
# MÀrkus: logimine lru_cache sees vÔib olla keeruline
# kuna see töötab ainult vahemĂ€lu möödalaskude korral. PĂŒsiva logimise jaoks
# on sageli parem logida vahemÀlustatud osast vÀljaspool vÔi toetuda cache_info-le.
print(f"(VahemÀlu möödalask/kÀivitamine) TÀidetakse: {func.__name__} argumentidega {args}, kwargs {kwargs}")
return func(*args, **kwargs)
return wrapper
return decorator
@cached_and_logged(maxsize=4)
def complex_calculation(a, b):
"""Teostab simuleeritud keerulist arvutust."""
print(f" - Teostatakse arvutus {a}+{b} jaoks...")
return a + b * 2
print(f"KÔne 1: {complex_calculation(1, 2)}") # VahemÀlu möödalask
print(f"KÔne 2: {complex_calculation(1, 2)}") # VahemÀlu tabamus
print(f"KÔne 3: {complex_calculation(3, 4)}") # VahemÀlu möödalask
print(f"KÔne 4: {complex_calculation(1, 2)}") # VahemÀlu tabamus
print(f"KÔne 5: {complex_calculation(5, 6)}") # VahemÀlu möödalask, vÔib vÀlja tÔrjuda (1,2) vÔi (3,4)
print(f"Funktsiooni nimi: {complex_calculation.__name__}")
print(f"Funktsiooni docstring: {complex_calculation.__doc__}")
print(f"VahemÀlu info: {complex_calculation.cache_info()}")
Selles kombineeritud decoratoris tagab `@wraps(func)`, et `complex_calculation`-i metaandmed sĂ€ilitatakse. `@lru_cache` decorator optimeerib tegelikku arvutust ja `wrapper`-i sees olev vĂ€ljatrĂŒkk kĂ€ivitatakse ainult vahemĂ€lu möödalaskude korral, pakkudes mĂ”ningat ĂŒlevaadet sellest, millal tegelik funktsioon on kutsutud. `maxsize` parameetrit saab kohandada `cached_and_logged` tehase funktsiooni kaudu.
JÀreldus: Globaalse Pythoni Arenduse VÔimaldamine
`functools` moodul, koos decoratoritega nagu `lru_cache`, `singledispatch` ja `wraps`, pakub Pythoni arendajatele kogu maailmas keerukaid tööriistu. Need decoratorid lahendavad tavalised tarkvaraarenduse vĂ€ljakutsed, alates jĂ”udluse optimeerimisest ja erinevate andmetĂŒĂŒpide kĂ€sitlemisest kuni koodi terviklikkuse ja arendaja tootlikkuse sĂ€ilitamiseni.
- `lru_cache` vĂ”imaldab teil rakenduste kiirust suurendada, vahemĂ€llu salvestades funktsioonide tulemused intelligentselt, mis on jĂ”udluskriitiliste globaalsete teenuste jaoks ĂŒlioluline.
- `singledispatch` vÔimaldab luua paindlikke ja laiendatavaid generilisi funktsioone, muutes koodi kohandatavaks laia hulga andmevormingute jaoks, mis esinevad rahvusvahelistes kontekstides.
- `wraps` on hĂ€davajalik hĂ€sti kĂ€ituvate decoratorite loomisel, tagades, et teie tĂ€iustatud funktsioonid jÀÀvad lĂ€bipaistvaks ja hooldatavaks, mis on koostöö ja globaalselt hajutatud arendusmeeskondade jaoks ĂŒlioluline.
Integreerides need tĂ€iustatud `functools` funktsioonid oma Pythoni arendustöövoogu, saate luua tĂ”husamaid, vastupidavamaid ja arusaadavamaid tarkvarasid. Kuna Python jĂ€tkab valikukeelena rahvusvahelistele arendajatele, annab nende vĂ”imsate decoratorite sĂŒgav mĂ”istmine teile kahtlemata konkurentsieelise.
Omandage need tööriistad, katsetage neid oma projektides ja avage oma globaalsete rakenduste jaoks Pythoni elegantsi ja jÔudluse uued tasemed.